﻿// Definition of OpenCV types referenced by CaptureWrapperOpenCV
// 
// FLMScan - Featured by FabLab Munich

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;

namespace FLMScan.OpenCV
{
    /// Black box cvcapture
    [StructLayout(LayoutKind.Sequential)]
    public struct CvCapture
    {
        public IntPtr ptr;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct CvSize
    {
        /// <summary>
        /// width of the rectangle
        /// </summary>
        public int width;

        /// <summary>
        /// height of the rectangle
        /// </summary>
        public int height;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="width">width of the rectangle</param>
        /// <param name="height">height of the rectangle</param>
        public CvSize(int width, int height)
        {
            this.width = width;
            this.height = height;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct CvRect
    {
        /// <summary>
        /// x-coordinate of the left-most rectangle corner[s]
        /// </summary>
        public int x;

        /// <summary>
        /// y-coordinate of the top-most or bottom-most rectangle corner[s]
        /// </summary>
        public int y;

        /// <summary>
        /// width of the rectangle
        /// </summary>
        public int width;

        /// <summary>
        /// height of the rectangle
        /// </summary>
        public int height;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="x">x-coordinate of the left-most rectangle corner[s]</param>
        /// <param name="y">y-coordinate of the top-most or bottom-most rectangle corner[s]</param>
        /// <param name="width">width of the rectangle</param>
        /// <param name="height">height of the rectangle</param>
        public CvRect(int x, int y, int width, int height)
        {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct IplImage
    {
        /// <summary>
        /// sizeof(IplImage) 
        /// </summary>
        public int nSize;

        /// <summary>
        /// version (=0)
        /// </summary>
        public int ID;

        /// <summary>
        /// Most of OpenCV functions support 1,2,3 or 4 channels 
        /// </summary>
        public int nChannels;

        /// <summary>
        /// ignored by OpenCV 
        /// </summary>
        public int alphaChannel;

        /// <summary>
        /// pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported 
        /// </summary>
        public int depth;

        /// <summary>
        /// ignored by OpenCV 
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] colorModel;

        /// <summary>
        /// ditto
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] channelSeq;

        /// <summary>
        /// 0 - interleaved color channels, 1 - separate color channels.
        /// cvCreateImage can only create interleaved images 
        /// </summary>
        public int dataOrder;

        /// <summary>
        /// 0 - top-left origin,
        /// 1 - bottom-left origin (Windows bitmaps style)
        /// </summary>
        public int origin;

        /// <summary>
        /// Alignment of image rows (4 or 8).
        /// OpenCV ignores it and uses widthStep instead 
        /// </summary>
        public int align;

        /// <summary>
        /// image width in pixels 
        /// </summary>
        public int width;

        /// <summary>
        /// image height in pixels 
        /// </summary>
        public int height;

        /// <summary>
        /// image ROI. when it is not NULL, this specifies image region to process 
        /// </summary>
        public IntPtr roi;

        /// <summary>
        /// must be NULL in OpenCV 
        /// </summary>
        public IntPtr maskROI;

        /// <summary>
        /// ditto
        /// </summary>
        public IntPtr imageId;

        /// <summary>
        /// ditto 
        /// </summary>
        public IntPtr tileInfo;

        /// <summary>
        /// image data size in bytes
        /// (=image->height*image->widthStep in case of interleaved data)
        /// </summary>
        public int imageSize;

        /// <summary>
        /// pointer to aligned image data 
        /// </summary>
        public IntPtr imageData;

        /// <summary>
        /// size of aligned image row in bytes 
        /// </summary>
        public int widthStep;

        /// <summary>
        /// border completion mode, ignored by OpenCV 
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] BorderMode;

        /// <summary>
        /// ditto
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] BorderConst;

        /// <summary>
        ///  pointer to a very origin of image data (not necessarily aligned) - it is needed for correct image deallocation 
        /// </summary>
        public IntPtr imageDataOrigin;

        /// <summary>
        /// Pointer to the unmanaged memory
        /// </summary>
        public IntPtr ptr;

        /// <summary>
        /// Converts this to Bitmap
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public static explicit operator Bitmap(IplImage img)
        {
            return CaptureWrapperOpenCV.ToBitmap(img, false);
        }
    }

    /// <summary>
    /// 2D point with floating-point coordinates
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct CvPoint2D32f
    {
        /// <summary>
        /// x-coordinate of the point
        /// </summary>
        public float x;

        /// <summary>
        /// y-coordinate of the point
        /// </summary>
        public float y;

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="x">x-coordinate</param>
        /// <param name="y">y-coordinate</param>
        public CvPoint2D32f(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    /// <summary>
    /// A container for 1-,2-,3- or 4-tuples of numbers
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct CvScalar
    {
        /// <summary>
        /// value 1
        /// </summary>
        public double val1;

        /// <summary>
        /// value 2
        /// </summary>
        public double val2;

        /// <summary>
        /// value 3
        /// </summary>
        public double val3;

        /// <summary>
        /// value 4
        /// </summary>
        public double val4;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="v1">value 1</param>
        /// <param name="v2">value 2</param>
        /// <param name="v3">value 3</param>
        /// <param name="v4">value 4</param>
        public CvScalar(double v1, double v2, double v3, double v4)
        {
            val1 = v1; val2 = v2; val3 = v3; val4 = v4;
        }
    }

    /// <summary>
    /// 2D point with integer coordinates
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct CvPoint
    {
        /// <summary>
        /// x-coordinate
        /// </summary>
        public int x;

        /// <summary>
        /// y-coordinate
        /// </summary>
        public int y;

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="x">x-coordinate</param>
        /// <param name="y">y-coordinate</param>
        public CvPoint(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    /// <summary>
    /// Multi-channel matrix
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct CvMat
    {
        /// <summary>
        /// CvMat signature (CV_MAT_MAGIC_VAL), element type and flags
        /// </summary>
        [FieldOffset(0)]
        public int type;

        /// <summary>
        /// full row length in bytes
        /// </summary>
        [FieldOffset(4)]
        public int step;

        /// <summary>
        /// for internal use only
        /// </summary>
        [FieldOffset(8)]
        public IntPtr refcount;

        /// <summary>
        /// for internal use only
        /// </summary>
        [FieldOffset(12)]
        public int hdr_refcount;

        /// <summary>
        /// underlaying data pointer
        /// </summary>
        [FieldOffset(16)]
        public IntPtr data;

        /// <summary>
        /// number of rows
        /// </summary>
        [FieldOffset(20)]
        public int rows;

        /// <summary>
        /// number of rows
        /// </summary>
        [FieldOffset(20)]
        public int height;

        /// <summary>
        /// number of columns
        /// </summary>
        [FieldOffset(24)]
        public int cols;

        /// <summary>
        /// number of columns
        /// </summary>
        [FieldOffset(24)]
        public int width;

        /// <summary>
        /// this pointer
        /// </summary>
        [FieldOffset(28)]
        public IntPtr ptr;
    }

    /// <summary>
    /// Termination criteria for iterative algorithms
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct CvTermCriteria
    {
        /// <summary>
        /// may be combination of
        /// CV_TERMCRIT_ITER 
        /// CV_TERMCRIT_EPS
        /// </summary>
        public int type;

        /// <summary>
        /// maximum number of iterations
        /// </summary>
        public int max_iter;

        /// <summary>
        /// accuracy to achieve
        /// </summary>
        public double epsilon;

        /// <summary>
        /// Constructor
        /// check termination criteria and transform it so that type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
        /// and both max_iter and epsilon are valid
        /// </summary>
        /// <param name="type"> may be combination of
        /// CV_TERMCRIT_ITER 
        /// CV_TERMCRIT_EPS</param>
        /// <param name="max_iter">maximum number of iterations</param>
        /// <param name="epsilon">accuracy to achieve</param>
        public CvTermCriteria(int type, int max_iter, double epsilon)
        {
            this.type = type;
            this.max_iter = max_iter;
            this.epsilon = epsilon;
        }
    }
}
